home *** CD-ROM | disk | FTP | other *** search
/ Scene Storm / Scene Storm - Volume 1.iso / coding / tools / gcc / libnixv1_0.lha / gnu / libnix-sources.lha / sources / startup / libinit.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-01-22  |  10.0 KB  |  294 lines

  1. /******************************************************************************/
  2. /*                                                                            */
  3. /* this works with gcc too and makes life easier                              */
  4. /*                                                                            */
  5. /******************************************************************************/
  6.  
  7. #define __USE_SYSBASE
  8.  
  9. /******************************************************************************/
  10. /*                                                                            */
  11. /* includes                                                                   */
  12. /*                                                                            */
  13. /******************************************************************************/
  14.  
  15. #include <exec/types.h>
  16. #include <exec/resident.h>
  17. #include <proto/exec.h>
  18. #include "libinit.h"
  19. #include "stabs.h"
  20.  
  21. /******************************************************************************/
  22. /*                                                                            */
  23. /* *** FIRST *** function - prevents a crash when called from CLI!            */
  24. /*                                                                            */
  25. /******************************************************************************/
  26.  
  27. int safefail()
  28. {
  29.   return -1;
  30. }
  31.  
  32. /******************************************************************************/
  33. /*                                                                            */
  34. /* defines                                                                    */
  35. /*                                                                            */
  36. /******************************************************************************/
  37.  
  38. #define SETA4(x) asm volatile ("movel a4,sp@-; movel %0,a4" :/* */: "g" (x))
  39. #define RESA4(x) asm volatile ("movel sp@+,a4;")
  40.  
  41. /******************************************************************************/
  42. /*                                                                            */
  43. /* imports                                                                    */
  44. /*                                                                            */
  45. /******************************************************************************/
  46.  
  47. extern const UWORD LibVersion;
  48. extern const UWORD LibRevision;
  49.  
  50. extern const BYTE LibName[];
  51. extern const BYTE LibIdString[];
  52.  
  53. extern APTR  __FuncTable__[];
  54.  
  55. extern int   __UserLibInit(_LIB *);
  56. extern void  __UserLibCleanUp();
  57.  
  58. /******************************************************************************/
  59. /*                                                                            */
  60. /* resident structure                                                         */
  61. /*                                                                            */
  62. /******************************************************************************/
  63.  
  64. const APTR InitTab[4];
  65.  
  66. static const struct Resident RomTag = {
  67.   RTC_MATCHWORD,
  68.   (struct Resident *)&RomTag,
  69.   (APTR)((&RomTag)+1),
  70.   RTF_AUTOINIT,
  71.   0,
  72.   NT_LIBRARY,
  73.   0,
  74.   (BYTE *)LibName,
  75.   (BYTE *)LibIdString,
  76.   (APTR)&InitTab
  77. };
  78.  
  79. /******************************************************************************/
  80. /*                                                                            */
  81. /* autoinit table for use with initial MakeLibrary()                          */
  82. /*                                                                            */
  83. /******************************************************************************/
  84.  
  85. const APTR InitTab[4] = {
  86.   (APTR)sizeof(_LIB),
  87.   (APTR)&__FuncTable__[1],
  88.   0,
  89.   (APTR)LibInit
  90. };
  91.  
  92. /******************************************************************************/
  93. /*                                                                            */
  94. /* support function(s) to be inlined                                          */
  95. /*                                                                            */
  96. /******************************************************************************/
  97.  
  98. static inline APTR __GetDataSeg()
  99. {
  100.   APTR res;
  101.   asm ("lea ___a4_init,%0" : "=a" (res));
  102.   return res;
  103. }
  104.  
  105. static inline ULONG __BSize()
  106. {
  107.   ULONG res;
  108.   asm ("movel #___bss_size,%0" : "=d" (res));
  109.   return res;
  110. }
  111.  
  112. static inline ULONG *__GetBssStart()
  113. {
  114.   ULONG *res;
  115.   asm ("lea __edata,%0" : "=a" (res));
  116.   return res;
  117. }
  118.  
  119. /******************************************************************************/
  120. /*                                                                            */
  121. /* initialization function called by MakeLibrary()                            */
  122. /*                                                                            */
  123. /******************************************************************************/
  124.  
  125. struct Library *LibInit()
  126. {
  127.   register APTR SegList asm("a0");
  128.   register struct Library *lib asm("d0");
  129.   _LIB *Library = (_LIB *)lib;
  130.   ULONG size;
  131.   int result;
  132.  
  133.   /* init library base */
  134.  
  135.   Library->LibNode.lib_Node.ln_Type = NT_LIBRARY;
  136.   Library->LibNode.lib_Node.ln_Name = (UBYTE *)LibName;
  137.   Library->LibNode.lib_Flags        = LIBF_CHANGED | LIBF_SUMUSED;
  138.   Library->LibNode.lib_Version      = (UWORD)LibVersion;
  139.   Library->LibNode.lib_Revision     = (UWORD)LibRevision;
  140.   Library->LibNode.lib_IdString     = (UBYTE *)LibIdString;
  141.   Library->SegList                  = SegList;
  142.   Library->DataSeg                  = __GetDataSeg();
  143.  
  144.   /* clear the bss part */
  145.  
  146.   if ((size=__BSize()))
  147.   {
  148.     ULONG *p=__GetBssStart();
  149.  
  150.     do
  151.     {
  152.       *p++=0;
  153.     }
  154.     while((size-=sizeof(ULONG)));
  155.   }
  156.  
  157.   /* now call user-init */
  158.  
  159.   SETA4(Library->DataSeg);
  160.   result=__UserLibInit(Library);
  161.   RESA4(0);
  162.  
  163.   /* all ok? */
  164.  
  165.   if (result!=0)
  166.     Library=NULL;
  167.  
  168.   /* this will be added to SysBase->LibList or NULL (init error) */
  169.  
  170.   return (struct Library *)Library;
  171. }
  172.  
  173. /******************************************************************************/
  174. /*                                                                            */
  175. /* LibOpen() will be called for every OpenLibrary()                           */
  176. /*                                                                            */
  177. /* !!! CAUTION: This function runs in a forbidden state !!!                   */
  178. /*                                                                            */
  179. /******************************************************************************/
  180.  
  181. struct Library *LibOpen()
  182. {
  183.   register struct Library *lib asm("a6");
  184.  
  185.   /* clear delayed expunge flag */
  186.  
  187.   lib->lib_Flags &= ~LIBF_DELEXP;
  188.  
  189.   /* one new user */
  190.  
  191.   lib->lib_OpenCnt++;
  192.  
  193.   /* return basePtr */
  194.  
  195.   return lib;
  196. }
  197.  
  198. /******************************************************************************/
  199. /*                                                                            */
  200. /* LibClose() will be called for every CloseLibrary()                         */
  201. /*                                                                            */
  202. /* !!! CAUTION: This function runs in a forbidden state !!!                   */
  203. /*                                                                            */
  204. /******************************************************************************/
  205.  
  206. APTR LibClose()
  207. {
  208.   register struct Library *lib asm("a6");
  209.   APTR SegList=0;
  210.  
  211.   /* one less user */
  212.  
  213.   if (--lib->lib_OpenCnt==0 && (lib->lib_Flags&LIBF_DELEXP))
  214.     SegList=LibExpunge();
  215.  
  216.   /* SegList or NULL (still in use) */
  217.  
  218.   return SegList;
  219. }
  220.  
  221. /******************************************************************************/
  222. /*                                                                            */
  223. /* remove library from memory if possible                                     */
  224. /*                                                                            */
  225. /* !!! CAUTION: This function runs in a forbidden state !!!                   */
  226. /*                                                                            */
  227. /******************************************************************************/
  228.  
  229. APTR LibExpunge()
  230. {
  231.   register struct Library *lib asm("a6");
  232.   _LIB *Library = (_LIB *)lib;
  233.   APTR SegList=0;
  234.  
  235.   /* set delayed expunge flag */
  236.  
  237.   Library->LibNode.lib_Flags |= LIBF_DELEXP;
  238.  
  239.   /* still in use? */
  240.  
  241.   if (Library->LibNode.lib_OpenCnt == 0)
  242.   {
  243.     ULONG NegSize;
  244.  
  245.     /* return the seglist for UnLoadSeg() */
  246.  
  247.     SegList = Library->SegList;
  248.  
  249.     /* remove library from SysBase->LibList */
  250.  
  251.     Remove((struct Node *)Library);
  252.  
  253.     /* now call user-exit */
  254.  
  255.     SETA4(Library->DataSeg);
  256.     __UserLibCleanUp();
  257.     RESA4(0);
  258.  
  259.     /* free library */
  260.  
  261.     NegSize = Library->LibNode.lib_NegSize;
  262.     FreeMem((APTR)((UBYTE *)Library-(UBYTE *)NegSize),NegSize+Library->LibNode.lib_PosSize);
  263.   }
  264.   return SegList;
  265. }
  266.  
  267. /******************************************************************************/
  268. /*                                                                            */
  269. /* a do nothing stub (required!)                                              */
  270. /*                                                                            */
  271. /******************************************************************************/
  272.  
  273. APTR LibExtFunc()
  274. {
  275.   return 0;
  276. }
  277.  
  278. /******************************************************************************/
  279. /*                                                                            */
  280. /* add these functions to 'funclist'                                          */
  281. /*                                                                            */
  282. /******************************************************************************/
  283.  
  284. ADD2LIST(LibOpen,__FuncTable__,22);
  285. ADD2LIST(LibClose,__FuncTable__,22);
  286. ADD2LIST(LibExpunge,__FuncTable__,22);
  287. ADD2LIST(LibExtFunc,__FuncTable__,22);
  288.  
  289. /******************************************************************************/
  290. /*                                                                            */
  291. /* end of libinit.c                                                           */
  292. /*                                                                            */
  293. /******************************************************************************/
  294.